package cs301.msflags;

import java.util.Vector;

import android.graphics.Point;

/**
 * @author John Olennikov
 * @author Kyanne Mayfield
 * @author Allie Seibert
 * @author Emilia Holbik
 * @version 12/7/2012
 * 
 *           This class will record the point on the board of an uncovered 
 *           space greater than one where surrounding covered spaces contain 
 *           unknown variables.
 */

public class Clue {

	/**
	 * the x position of an uncovered space with unknown neighbors
	 */

	private int clueXPos;

	/**
	 * the y position of an uncovered space with unknown neighbors
	 */

	private int clueYPos;

	/**
	 * the coordinates surrounding the clueId with unknown quantities
	 */

	private Vector<Point> unknownSpaces;

	/**
	 * a clue who's unknownSpaces is a subset to that of this clue
	 */

	private Clue subset;

	/**
	 * boolean that tells if the clue has a subset
	 */

	private boolean hasSubset;

	/**
	 * Initializes the clue
	 * 
	 * @param xPos  the x position of the clue id
	 * @param xPos  the x position of the clue id
	 * @param spaces  the initial unknownSpaces
	 */

	public Clue(int xPos, int yPos, Vector<Point> spaces) {
		this.clueXPos = xPos;
		this.clueYPos = yPos;
		hasSubset = false;
		this.unknownSpaces = spaces;
	}

	/**
	 * @return  unkownSpaces surrounding this space
	 */

	public Vector<Point> getPoints() {
		return unknownSpaces;
	}

	/**
	 * @return  all spaces (which are points), including those in a subset
	 */
	public Vector<Point> getAllPoints() {
		Vector<Point> all = unknownSpaces;
		if (hasSubset)
			all.addAll(subset.getPoints());
		return all;
	}

	/**
	 * @return  the x position of the space whose probability of a mine 
	 *          is high enough for flagging
	 */
	public int getX() {
		return this.clueXPos;
	}

	/**
	 * @return  the y position of the space whose probability of a mine 
	 *          is high enough for flagging
	 */

	public int getY() {
		return this.clueYPos;

	}

	/**
	 * Returns true if location is in the unkownSpaces vector and removes it
	 * 
	 * @param location  a point to be removed from the vector
	 * @return  true if location is in the unknownSpaces vector
	 */

	public boolean remove(Point location) {
		boolean removed = false;
		//if this location is in the unknownSpaces vector
		if (hasSubset) {
			removed = subset.remove(location);
			//reset subset for later uses to false
			if (subset.getPoints().isEmpty()) {
				hasSubset = false;
			}
		}
		if (!removed) {
			removed = this.unknownSpaces.remove(location);
		}
		return removed;
	}

	/**
	 * Returns true if location is in the unkownSpaces vector and removes it
	 * 
	 * @param location  a point to be removed from the vector
	 */
	public boolean removeAll(Vector<Point> otherClue) {
		return this.unknownSpaces.removeAll(otherClue);
	}

	/**
	 * Set the subset (which determines the probabilities that a surrounding
	 * space has a mine) for the given clue.
	 * 
     * @param clue  the clue to which a subset has been given
     * @return  whether this clue has a subset
     */
	public boolean designateSubset(Clue clue) {
		if (hasSubset) {
			return false;
		}
		if (unknownSpaces.containsAll(clue.getPoints())) {
			subset = clue;
			hasSubset = true;
			unknownSpaces.removeAll(subset.getPoints());
		}
		return hasSubset;
	}

	/**
	 * @return  whether or not this clue has a subset
	 */
	public boolean hasSubset() {
		return hasSubset;
	}

	/**
	 * @return  the subset for this clue
	 */
	public Clue getSubset() {
		return subset;
	}

}